package com.sky.service.impl;

import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.vo.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Service;


@Slf4j
@Service
@RequiredArgsConstructor
public class ReportServiceImpl implements ReportService {

    private final ReportMapper reportMapper;

    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        List<Map<String,Object>> mapList = reportMapper.selectStatisticsBetweenOrderTime(begin,end);

        //处理时间
        String joinedTime = mapList.stream()
                .map(item -> (String) item.get("order_time_format"))
                .collect(Collectors.joining(","));

        //处理金额
        String joinedAmount = mapList.stream()
                .map(item -> (BigDecimal) item.get("sum_amount"))
                .map(BigDecimal::toString)
                .collect(Collectors.joining(","));

        turnoverReportVO.setDateList(joinedTime);
        turnoverReportVO.setTurnoverList(joinedAmount);
        return turnoverReportVO;
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        UserReportVO userReportVO = new UserReportVO();
        List<Map<String,Object>> mapList = reportMapper.selectStatisticsBetweenCreateTime(begin,end);

        String joinedTime = mapList.stream()
                .map(item -> (String) item.get("create_time_format"))
                .collect(Collectors.joining(","));

        String countDay = mapList.stream()
                .map(item -> (Long) item.get("count_day"))
                .map(Objects::toString)
                .collect(Collectors.joining(","));

        String countAll = mapList.stream()
                .map(item -> (Long) item.get("count"))
                .map(Objects::toString)
                .collect(Collectors.joining(","));


        userReportVO.setDateList(joinedTime);
        userReportVO.setTotalUserList(countAll);
        userReportVO.setNewUserList(countDay);
        return userReportVO;
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        OrderReportVO orderReportVO = new OrderReportVO();
        List<Map<String,Object>> mapList = reportMapper.selectordersStatisticsBetweenCreateTime(begin,end);

        String joinedTime = mapList.stream()
                .map(item -> (String) item.get("order_time_format"))
                .collect(Collectors.joining(","));

        List<Long> countAll = mapList.stream()
                .map(item -> (Long) item.get("count_all"))
                .collect(Collectors.toList());
        Optional<Long> optionalCountAllLong = countAll.stream().reduce(Long::sum);
        Long aCountAllLong = 0L;
        if (optionalCountAllLong.isPresent()){
            aCountAllLong = optionalCountAllLong.get();
        }

        List<Long> countValid = mapList.stream()
                .map(item -> (Long) item.get("count_valid"))
                .collect(Collectors.toList());
        Optional<Long> optionalCountValidLong = countValid.stream().reduce(Long::sum);
        Long aCountValidLong = 0L;
        if (optionalCountValidLong.isPresent()){
            aCountValidLong = optionalCountValidLong.get();
        }

        Double orderCompletionRate = aCountValidLong.doubleValue() / aCountAllLong.doubleValue();

        String orderCountList = countAll.stream().map(Objects::toString).collect(Collectors.joining(","));
        String validCountList = countAll.stream().map(Objects::toString).collect(Collectors.joining(","));

        orderReportVO.setDateList(joinedTime);
        orderReportVO.setOrderCountList(orderCountList);
        orderReportVO.setValidOrderCountList(validCountList);
        orderReportVO.setTotalOrderCount(Math.toIntExact(aCountAllLong));
        orderReportVO.setValidOrderCount(Math.toIntExact(aCountValidLong));
        orderReportVO.setOrderCompletionRate(orderCompletionRate);
        return orderReportVO;
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();
        List<Map<String,Object>> mapList = reportMapper.top10(begin,end);

        String nameJoined = mapList.stream()
                .map(item -> (String) item.get("name"))
                .collect(Collectors.joining(","));

        String sumJoined = mapList.stream()
                .map(item -> (BigDecimal) item.get("sum"))
                .map(BigDecimal::intValue)
                .map(Objects::toString)
                .collect(Collectors.joining(","));
        salesTop10ReportVO.setNameList(nameJoined);
        salesTop10ReportVO.setNumberList(sumJoined);
        return salesTop10ReportVO;
    }

    @Override
    public void export(HttpServletResponse response) {
        try {
            //1.todo 读取模板
            InputStream stream = this.getClass().getClassLoader().getResourceAsStream("template\\operationalDataReportTemplate.xlsx");
            Workbook workbook = WorkbookFactory.create(stream);
            Sheet sheet1 = workbook.getSheetAt(0);

            //2.todo 查询数据进行填充
            LocalDate now = LocalDate.now();
            LocalDate begin = now.plusDays(-30L);
            LocalDate end = now.plusDays(-1L);
            String time = "生成时间:" + begin + "至" + end;
            //行
            Row row2 = sheet1.getRow(1);
            Cell cell22 = row2.getCell(1);
            cell22.setCellValue(time);
            BusinessDataVO businessDataVO = reportMapper.selecttBusinessDataVO(begin,end);

            Row row4 = sheet1.getRow(3);
            Row row5 = sheet1.getRow(4);
            Cell cell42 = row4.getCell(2);
            Cell cell44 = row4.getCell(4);
            Cell cell46 = row4.getCell(6);
            Cell cell52 = row5.getCell(2);
            Cell cell54 = row5.getCell(4);

//            BusinessDataVO businessDataVO = new BusinessDataVO();
//            businessDataVO.setTurnover(reportMapper.selectTurnover(begin,end));
//            businessDataVO.setValidOrderCount(reportMapper.selectValidOrderCount(begin,end));
//            businessDataVO.setOrderCompletionRate(reportMapper.selectOrderCompletionRate(begin,end));
//            businessDataVO.setUnitPrice(reportMapper.selectUnitPrice(begin,end));
//            businessDataVO.setNewUsers(reportMapper.selectNewUsers(begin,end));

            //订单完成率百分百转换
            BigDecimal bigDecimal = BigDecimal.valueOf(businessDataVO.getOrderCompletionRate())
                    .multiply(BigDecimal.valueOf(100))
                    .setScale(2, RoundingMode.HALF_UP);

            cell42.setCellValue("$" + businessDataVO.getTurnover());
            cell44.setCellValue(bigDecimal + "%");
            cell46.setCellValue(businessDataVO.getNewUsers());
            cell52.setCellValue(businessDataVO.getValidOrderCount());
            cell54.setCellValue("$" + businessDataVO.getUnitPrice());

            List<BusinessDataVO> businessDataVOList = reportMapper.selectBusinessDataVOWithDay(begin,end);
            for (int i = 0; i < businessDataVOList.size(); i++) {
                BusinessDataVO dataVO = businessDataVOList.get(i);
                int rowIndex = i + 7;
                Row row = sheet1.getRow(rowIndex);
                BigDecimal orderCompletionRate = BigDecimal.valueOf(dataVO.getOrderCompletionRate())
                        .multiply(BigDecimal.valueOf(100))
                        .setScale(2, RoundingMode.HALF_UP);
                row.getCell(1).setCellValue(dataVO.getFormatOrderTime());
                row.getCell(2).setCellValue("$" + dataVO.getTurnover());
                row.getCell(3).setCellValue(dataVO.getValidOrderCount());
                row.getCell(4).setCellValue(orderCompletionRate + "%");
                row.getCell(5).setCellValue("$" + dataVO.getUnitPrice());
                row.getCell(6).setCellValue(dataVO.getNewUsers());
            }
            //3.todo 写好Excel放进响应response
            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (Exception e) {
            log.info("导出Excel失败", e);
        }
    }
}
